package com.yiren.backstage.judge.services.standard.impl;

import android.content.Context;

import com.yiren.backstage.currency.bean.CarStateBean;
import com.yiren.backstage.currency.constant.AutoJudgeConstant;
import com.yiren.backstage.currency.entity.GradeStandardEntity;
import com.yiren.backstage.currency.entity.JudgeDetailsEntity;
import com.yiren.backstage.currency.entity.JudgeResultEntity;
import com.yiren.backstage.currency.entity.ProjectJudgeEntity;
import com.yiren.backstage.currency.entity.StateMonitorEntity;
import com.yiren.backstage.currency.enums.DualEnum;
import com.yiren.backstage.currency.enums.ExecuteTypeEnum;
import com.yiren.backstage.currency.enums.ResultStateEnum;
import com.yiren.backstage.currency.enums.TaskStateEnum;
import com.yiren.backstage.currency.utils.MessageUtil;
import com.yiren.backstage.judge.bean.NodeBean;
import com.yiren.backstage.judge.handler.AutoJudgeHandler;
import com.yiren.backstage.judge.services.standard.CheckCarStateIsAccordService;
import com.yiren.backstage.judge.services.standard.IAutoJudgeThreadService;
import com.yiren.backstage.judge.services.standard.ICheckElementResultService;
import com.yiren.backstage.judge.thread.AutoJudgeThread;

import java.util.List;

/**
 * Time:2021/11/11 15:03
 * Author:xiaozan
 * Description:自动评判线程 服务
 */
public class AutoJudgeThreadServiceImpl  implements IAutoJudgeThreadService {

    private CheckCarStateIsAccordService checkCarStateIsAccordService;

    private ICheckElementResultService iCheckElementResultService;

    private AutoJudgeHandler autoJudgeHandler;

    public AutoJudgeThreadServiceImpl(Context context,AutoJudgeHandler autoJudgeHandler){
        this.autoJudgeHandler = autoJudgeHandler;
        checkCarStateIsAccordService = new CheckCarStateIsAccordService(context,autoJudgeHandler.getiExamStateCallBack());
        iCheckElementResultService = new CheckElementResultServiceImpl(context);
    }

    @Override
    public ResultStateEnum executeResult(AutoJudgeThread autoJudgeThread) {
        JudgeDetailsEntity judgeDetailsEntity =(JudgeDetailsEntity) autoJudgeThread.getmTaskNode().getEntity();
        ExecuteTypeEnum conditionType = ExecuteTypeEnum.valueOf(judgeDetailsEntity.getConditionType());
        //条件要素
        boolean accordConditionElement = iCheckElementResultService.accordConditionElement(autoJudgeThread,judgeDetailsEntity,autoJudgeThread.getmStartCarState(),autoJudgeThread.getmStartTime());

        //判定是否符合车辆状态，如果车辆状态为空，默认为不符合车辆状态（空等待）
        boolean accordCarState = false;
        StateMonitorEntity stateMonitorEntity = judgeDetailsEntity.getStateMonitorEntity();
        if (null != stateMonitorEntity) {
            accordCarState = checkCarStateIsAccordService.isAccordCurrentCarState(autoJudgeThread,autoJudgeThread.getmStartCarState(), stateMonitorEntity.getMonitorCountEntitys());
        }else{
            accordCarState = true;
        }

        //执行要素是否符合
        boolean accordExecuteElement =false;
        switch (conditionType) {
            //等待
            case WAIT:
                accordExecuteElement = iCheckElementResultService.waitAccordExecuteElement(judgeDetailsEntity,accordCarState);
                //当条件和车辆状态没符合时，返回执行失败
                if (!accordConditionElement && !accordExecuteElement) {
                    return ResultStateEnum.FAIL;
                } else {
                    if (accordExecuteElement)  return ResultStateEnum.SUCCESS;
                }
                break;
            //后等待(例子：车速大于3码 后等待 车门是否关闭)
            case AFTER_WAIT:
                //当条件要素不符合后再判断执行要素
                if (!accordConditionElement) {
                    return iCheckElementResultService.afterWaitAccordExecuteElement(judgeDetailsEntity,accordCarState);
                }
                break;
            //累计
            case TOTAL:
                accordExecuteElement = iCheckElementResultService.totalAccordExecuteElement(judgeDetailsEntity,accordCarState);
                //当条件和车辆状态没符合时，返回执行失败
                if (!accordConditionElement && !accordExecuteElement) {
                    //执行失败
                    return ResultStateEnum.FAIL;
                } else {
                    if (accordExecuteElement)  return ResultStateEnum.SUCCESS;
                }
                break;
        }
        return ResultStateEnum.EXECUTING;
    }

    @Override
    public void runExecuteResultWith(AutoJudgeThread autoJudgeThread,ResultStateEnum resultState) {
        AutoJudgeThread mRootTask = autoJudgeThread.getmRootTask();
        NodeBean gradeNode = autoJudgeThread.getmTaskNode();
        ProjectJudgeEntity projectJudgeEntity = gradeNode.getProjectJudgeEntity();
        JudgeDetailsEntity judgeDetailsEntity = (JudgeDetailsEntity) gradeNode.getEntity();
        List<JudgeResultEntity> judgeResultEntities = judgeDetailsEntity.getJudgeDetailsResultEntitys();
        for (JudgeResultEntity judgeResultEntity : judgeResultEntities) {
            //获取对应执行结果
            if (resultState == ResultStateEnum.valueOf(judgeResultEntity.getResultType())) {
                mRootTask.setmExecutedNodeCount(mRootTask.getmExecutedNodeCount()+1);
                //将扣分对象保存至扣分列表中
                if (DualEnum.valueOf(judgeResultEntity.getExecuteGrade()) == DualEnum.YES && null != judgeResultEntity.getGradeStandardEntity()) {
                    GradeStandardEntity gradeStandardEntity = judgeResultEntity.getGradeStandardEntity();
                    gradeStandardEntity.setProjectEntity(projectJudgeEntity.getProject());
                    gradeStandardEntity.setCode(projectJudgeEntity.getId()+"-"+judgeResultEntity.getJudgeDetailsEntity().getId());
                    autoJudgeHandler.sendMessage(MessageUtil.newMessage(AutoJudgeConstant.ADD_PROJECT_GRADE, gradeStandardEntity));
                }

                //是否继续执行
                if (null != gradeNode.getChildren() && gradeNode.getChildren().size() > 0 && DualEnum.valueOf(judgeResultEntity.getContinueExecute()) == DualEnum.YES) {
                    //执行子任务
                    autoJudgeHandler.sendMessage(MessageUtil.newMessage(AutoJudgeConstant.CONTINUE_EXECUTE, autoJudgeThread));
                }

                //当前节点不继续执行子级时，当前节点的子级节点数大于0  递归取消节点
                if (DualEnum.valueOf(judgeResultEntity.getContinueExecute()) != DualEnum.YES && gradeNode.getChildren().size() > 0) {
                    recursionCancelGradeNodeExecute(mRootTask,gradeNode);
                    //减去当前节点
                    mRootTask.setmExecutedNodeCount(mRootTask.getmExecutedNodeCount()-1);
                }

                //终结当前项目
                if (DualEnum.valueOf(judgeResultEntity.getOverProject()) == DualEnum.YES) {
                    mRootTask.setmTaskState(TaskStateEnum.FINISH);
                    autoJudgeHandler.sendMessage(MessageUtil.newMessage(AutoJudgeConstant.PLAY_PROJECT_END_VOICE,mRootTask.getProjectEntity()));
                }

                //是否自动结束考试
                if (DualEnum.valueOf(judgeResultEntity.getEndExam()) == DualEnum.YES) {
                    //终结项目
                    mRootTask.setmTaskState(TaskStateEnum.FINISH);
                    //播报项目结束语音
                    autoJudgeHandler.sendMessage(MessageUtil.newMessage(AutoJudgeConstant.PLAY_PROJECT_END_VOICE,mRootTask.getProjectEntity()));
                    //结束考试
                    autoJudgeHandler.sendMessage(MessageUtil.newMessage(AutoJudgeConstant.AUTO_END_EXAM, true));
                }
                break;
            }
        }
    }

    /**
     * 递归取消评分节点执行
     * @param mRootTask
     * @param node
     */
    private void recursionCancelGradeNodeExecute(AutoJudgeThread mRootTask,NodeBean node) {
        mRootTask.setmExecutedNodeCount(mRootTask.getmExecutedNodeCount()+1);
        for (int i = 0; i < node.getChildren().size(); i++) {
            NodeBean currentNode = node.getChildren().get(i);
            recursionCancelGradeNodeExecute(mRootTask,currentNode);
        }
    }
}
